﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;
using Microsoft.SharePoint.WebControls;

namespace VH.SharePoint.Api.Pages
{
    public partial class BlogApiSettings : LayoutsPageBase
    {
        #region Security management
        //Manage Web and Manage Lists
        protected override SPBasePermissions RightsRequired
        {
            get
            {
                return SPBasePermissions.ManageWeb | SPBasePermissions.ManageLists | DefaultLayoutsRights;
            }
        }
        //Unsupported read only site
        protected override bool SupportsReadOnlySite
        {
            get
            {
                return false;
            }
        }
        #endregion

        #region Properties
        private BlogWeb _blog;
        protected BlogWeb Blog {
            get { return _blog ?? (_blog = BlogWeb.GetBlogWeb(this.Web)); }
        }

        private IEnumerable<SPList> _documentLiraries;
        protected IEnumerable<SPList> DocumentLibraries {
            get { return _documentLiraries ?? (_documentLiraries = this.Web.GetListsOfType(SPBaseType.DocumentLibrary).Cast<SPList>().OrderBy(l => l.Title)); }
        }

        #endregion

        #region Constructor
        public BlogApiSettings()
        {
            //Make sure the user can access the page before loading it.
            RightsCheckMode = RightsCheckModes.OnPreInit;
        }
        #endregion

        #region Page Loading
        protected void Page_Load(object sender, EventArgs e)
        {
            if (IsPostBack) return;
            DisplayControls(Blog.IsEnabled);
            LoadEnabling();
            LoadAllowingScripts();
            LoadPageLibraries();
            LoadMediaLibraries();
            LoadSubFolderName();
        }

        private void LoadEnabling()
        {
            rlEnabled.SelectedValue = Blog.IsEnabled.ToString();
        }

        private void LoadAllowingScripts()
        {
            rlAllowScripts.SelectedValue = Blog.ScriptTagsEnabled.ToString();
        }

        private void LoadPageLibraries()
        {
            lstPageLibraries.DataSource = DocumentLibraries.Where(l => IsInPageTemplate((int)l.BaseTemplate));
            lstPageLibraries.DataBind();
            lstPageLibraries.SelectedValue = this.Blog.PostLibraryId.ToString();
        }

        private void LoadMediaLibraries()
        {
            lstMediaLibraries.DataSource = DocumentLibraries.Where(l => IsInMediaTemplate((int)l.BaseTemplate));
            lstMediaLibraries.DataBind();
            lstMediaLibraries.SelectedValue = this.Blog.MediaLibraryId.ToString();
        }

        private void LoadSubFolderName()
        {
            txtDefaultSubFolder.Text = Blog.MediaFolderName;
        }

        #endregion

        #region Page Validation
        protected void okButton_OnClick(object sender, EventArgs e)
        {
            if (!Page.IsValid) return;
            using (var operation = new SPLongOperation(this.Page))
            {
                operation.Begin();
                try
                {
                    UpdateBlog();

                    EndOperation(PageResult.Ok);
                }
                catch (Exception ex)
                {
                    EndOperation(PageResult.Invalid, ex.ToString());
                }
                finally
                {

                }
            }
        }

        private void EndOperation(PageResult result)
        {
            EndOperation(result, string.Empty);
        }

        private void EndOperation(PageResult result, String content)
        {
            try
            {
                if (result == PageResult.Invalid)
                    SPUtility.TransferToErrorPage(content);
                if (this.IsDialogMode)
                {
                    Page.Response.Clear();
                    Page.Response.Write(String.Format(CultureInfo.InvariantCulture, "<script type=\"text/javascript\">window.frameElement.commonModalDialogClose({0}, {1});</script>", new object[] { (int)result, String.IsNullOrEmpty(content) ? "null" : String.Format("\"{0}\"", content) }));
                    Page.Response.End();
                }
                else
                {
                    SPUtility.Redirect(SPContext.Current.Web.ServerRelativeUrl.TrimEnd('/') + "/_layouts/settings.aspx", SPRedirectFlags.UseSource | SPRedirectFlags.Trusted, Context);
                }
            }
            catch (ThreadAbortException)
            {
                // Don’t do anything, this error can occur because the SPLongOperation.End
                // performs a Response.Redirect internally and doesnt take into account
                // that other code might still be executed
            }
        }
        #endregion

        #region Blog processing
        private void UpdateBlog()
        {
            SetEnabling();
            SetPageLibrary();
            SetMediaLibrary();
            SetMediaFolder();
            SetAllowingScripts();
            
            Blog.Update();
        }

        private void SetEnabling()
        {
            var enabled = bool.Parse(rlEnabled.SelectedValue);
            if(enabled)
                Blog.EnableBlogApi();
            else
                Blog.DisableBlogApi();
        }

        private void SetPageLibrary()
        {
            Blog.PostLibraryId = new Guid(lstPageLibraries.SelectedValue);
        }

        private void SetMediaLibrary()
        {
            Blog.MediaLibraryId = new Guid(lstMediaLibraries.SelectedValue);
        }

        private void SetMediaFolder()
        {
            Blog.MediaFolderName = txtDefaultSubFolder.Text;
        }

        private void SetAllowingScripts()
        {
            var enabled = bool.Parse(rlAllowScripts.SelectedValue);
            Blog.ScriptTagsEnabled = enabled;
        }
        #endregion

        #region UI Management
        protected void rlEnabled_OnSelectedIndexChanged(object sender, EventArgs e)
        {
            var enabled = bool.Parse(rlEnabled.SelectedValue);
            DisplayControls(enabled);
        }

        private void DisplayControls(bool visible)
        {
            ifsMediasLibrary.Visible = visible;
            vTxtDefaultSubFolder.Enabled = visible;
            vLstPageLibraries.Enabled = visible;
            vLstMediaLibraries.Enabled = visible;
            ifsPageLibrary.Visible = visible;
            ifsSriptsEnabled.Visible = visible;
        }

        #endregion

        private static Boolean IsInPageTemplate(Int32 value)
        {
            return IsIn<PageTemplate>(value);
        }
        private static Boolean IsInMediaTemplate(Int32 value)
        {
            return IsIn<MediaTemplate>(value);
        }
        private static Boolean IsIn<T>(Int32 value)
        {
            var templates = Enum.GetValues(typeof(T));
            var template = templates.Cast<Int32>().Contains(value);
            //var template = Enum.Parse(typeof(PageTemplate), value.ToString(CultureInfo.InvariantCulture));
            return template;

        }
    }

    public enum PageTemplate
    {
        WikiPageLibrary = 119,
        PublishingPageLibrary = 850
    }

    public enum MediaTemplate
    {
        PublishingLibrary = 851,
        DocumentLibrary = 101
    }

    internal enum PageResult
    {
        Invalid=-1,
        Cancel = 0,
        Ok = 1
    }
}
